package com.lefevre.cms.service.message.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lefevre.cms.bean.QueryResult;
import com.lefevre.cms.bean.message.SubscriptionSystemNotify;
import com.lefevre.cms.bean.message.SystemNotify;
import com.lefevre.cms.mapper.SubscriptionSystemNotifyMapper;
import com.lefevre.cms.mapper.SystemNotifyMapper;
import com.lefevre.cms.service.besa.DaoSupport;
import com.lefevre.cms.service.message.SystemNotifyService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 系统通知
 *
 * @author Lefevre
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class SystemNotifyServiceImpl extends DaoSupport<SystemNotify> implements SystemNotifyService {

    @Resource
    private SystemNotifyMapper baseMapper;
    @Resource
    private SubscriptionSystemNotifyMapper subscriptionSystemNotifyMapper;

    /**
     * 根据Id查询系统通知
     *
     * @param systemNotifyId 系统通知Id
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public SystemNotify findById(Long systemNotifyId) {
        return baseMapper.selectById(systemNotifyId);
    }


    /**
     * 根据用户Id查询订阅系统通知分页
     *
     * @param userId     用户Id
     * @param status     状态
     * @param firstIndex 索引开始,即从哪条记录开始
     * @param maxResult  获取多少条数据
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public QueryResult<SubscriptionSystemNotify> findSubscriptionSystemNotifyByUserId(Long userId, Integer status, int firstIndex, int maxResult) {
        QueryResult<SubscriptionSystemNotify> qr = new QueryResult<>();

        LambdaQueryWrapper<SubscriptionSystemNotify> wrapper = new LambdaQueryWrapper<>();
        String status_sql = "";
        if (status != null) {
            wrapper.lt(SubscriptionSystemNotify::getStatus, status);
        }
        Page<SubscriptionSystemNotify> subscriptionSystemNotifyPage = subscriptionSystemNotifyMapper.selectPage(new Page<>(firstIndex, maxResult), wrapper);
        qr.setResultlist(subscriptionSystemNotifyPage.getRecords());
        qr.setTotalrecord(subscriptionSystemNotifyPage.getTotal());
        return qr;
    }


    /**
     * 查询用户最新订阅系统通知Id
     *
     * @param userId 用户Id
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public Long findMaxSystemNotifyIdByUserId(Long userId) {
        List<SubscriptionSystemNotify> list = subscriptionSystemNotifyMapper.selectList(new LambdaQueryWrapper<SubscriptionSystemNotify>()
                .eq(SubscriptionSystemNotify::getUserId, userId)
                .orderByDesc(SubscriptionSystemNotify::getSystemNotifyId));
        if (list.size() > 0) {
            return list.get(0).getSystemNotifyId();
        }
        return null;
    }


    /**
     * 根据发送时间查询系统通知(仅返回id和sendTime字段)
     *
     * @param sendTime 发送时间
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public Map<Long, Date> findSystemNotifyBySendTime(Date sendTime) {
        Map<Long, Date> map = new HashMap<>();
        List<SystemNotify> list = baseMapper.selectList(new LambdaQueryWrapper<SystemNotify>().ge(SystemNotify::getSendTime, sendTime));
        for (SystemNotify systemNotify : list) {
            map.put(systemNotify.getId(), systemNotify.getSendTime());
        }
        return map;
    }

    /**
     * 根据系统通知Id查询系统通知(仅返回id和sendTime字段)
     *
     * @param systemNotifyId 系统通知Id
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public Map<Long, Date> findSystemNotifyById(Long systemNotifyId) {
        Map<Long, Date> map = new HashMap<>();
        List<SystemNotify> systemNotifies = baseMapper.selectList(new LambdaQueryWrapper<SystemNotify>().gt(SystemNotify::getId, systemNotifyId));
        for (SystemNotify systemNotify : systemNotifies) {
            map.put(systemNotify.getId(), systemNotify.getSendTime());
        }
        return map;
    }


    /**
     * 设置订阅系统通知状态为已读
     *
     * @param userId                         用户Id
     * @param subscriptionSystemNotifyIdList 订阅系统通知Id集合
     */
    public Integer updateSubscriptionSystemNotifyStatus(Long userId, List<String> subscriptionSystemNotifyIdList) {
        return subscriptionSystemNotifyMapper.update(null, new LambdaUpdateWrapper<SubscriptionSystemNotify>()
                .set(SubscriptionSystemNotify::getStatus, 20)
                .set(SubscriptionSystemNotify::getReadTime, new Date())
                .in(SubscriptionSystemNotify::getId, subscriptionSystemNotifyIdList)
                .lt(SubscriptionSystemNotify::getStatus, 20));
    }


    /**
     * 根据用户Id查询最早的未读系统通知Id
     *
     * @param userId 用户Id
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public Long findMinUnreadSystemNotifyIdByUserId(Long userId) {
        List<SubscriptionSystemNotify> subscriptionSystemNotifies = subscriptionSystemNotifyMapper.selectList(
                new LambdaQueryWrapper<SubscriptionSystemNotify>()
                        .eq(SubscriptionSystemNotify::getUserId, userId)
                        .eq(SubscriptionSystemNotify::getStatus, 10)
                        .orderByAsc(SubscriptionSystemNotify::getSystemNotifyId));
        if (subscriptionSystemNotifies.size() > 0) {
            return subscriptionSystemNotifies.get(0).getSystemNotifyId();
        }
        return null;
    }

    /**
     * 根据用户Id查询最大的已读系统通知Id
     *
     * @param userId 用户Id
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public Long findMaxReadSystemNotifyIdByUserId(Long userId) {
        List<SubscriptionSystemNotify> subscriptionSystemNotifies = subscriptionSystemNotifyMapper.selectList(new LambdaQueryWrapper<SubscriptionSystemNotify>()
                .eq(SubscriptionSystemNotify::getUserId, userId)
                .ge(SubscriptionSystemNotify::getStatus, 20)
                .le(SubscriptionSystemNotify::getStatus, 120)
                .ne(SubscriptionSystemNotify::getStatus, 110)
                .orderByDesc(SubscriptionSystemNotify::getSystemNotifyId));
        if (subscriptionSystemNotifies.size() > 0) {
            return subscriptionSystemNotifies.get(0).getSystemNotifyId();
        }
        return null;
    }


    /**
     * 根据起始系统通知Id查询系统通知数量(不含起始系统通知Id行)
     *
     * @param start_systemNotifyId 起始系统通知Id
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public Long findSystemNotifyCountBySystemNotifyId(Long start_systemNotifyId) {
        return baseMapper.selectCount(new LambdaQueryWrapper<SystemNotify>().gt(SystemNotify::getId, start_systemNotifyId)
                .orderByAsc(SystemNotify::getId));
    }

    /**
     * 根据起始系统通知发送时间查询系统通知数量
     *
     * @param start_sendTime 起始系统通知发送时间
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public Long findSystemNotifyCountBySendTime(Date start_sendTime) {
        return baseMapper.selectCount(new LambdaQueryWrapper<SystemNotify>().ge(SystemNotify::getSendTime, start_sendTime)
                .orderByAsc(SystemNotify::getId));
    }


    /**
     * 保存订阅系统通知
     *
     * @param subscriptionSystemNotifyList 订阅系统通知集合
     */
    public void saveSubscriptionSystemNotify(List<Object> subscriptionSystemNotifyList) {
        for (Object subscriptionSystemNotify : subscriptionSystemNotifyList) {
            subscriptionSystemNotifyMapper.insert((SubscriptionSystemNotify) subscriptionSystemNotify);
        }
    }

    /**
     * 软删除订阅系统通知
     *
     * @param userId                     用户Id
     * @param subscriptionSystemNotifyId 订阅系统通知Id
     */
    public Integer softDeleteSubscriptionSystemNotify(Long userId, String subscriptionSystemNotifyId) {
        SubscriptionSystemNotify subscriptionSystemNotify = subscriptionSystemNotifyMapper.selectOne(new LambdaQueryWrapper<SubscriptionSystemNotify>()
                .eq(SubscriptionSystemNotify::getId, subscriptionSystemNotifyId)
                .eq(SubscriptionSystemNotify::getUserId, userId)
                .lt(SubscriptionSystemNotify::getStatus, 100));
        subscriptionSystemNotify.setStatus(subscriptionSystemNotify.getStatus() + 100);
        return subscriptionSystemNotifyMapper.updateById(subscriptionSystemNotify);
    }

    /**
     * 删除用户所有订阅系统通知
     *
     * @param userIdList 用户Id集合
     */
    public Integer deleteUserSubscriptionSystemNotify(List<Long> userIdList) {
        return subscriptionSystemNotifyMapper.delete(new LambdaUpdateWrapper<SubscriptionSystemNotify>().in(SubscriptionSystemNotify::getUserId, userIdList));
    }

    /**
     * 还原被用户删除的订阅系统通知
     *
     * @param subscriptionSystemNotifyId 订阅系统通知Id
     */
    public Integer reductionSubscriptionSystemNotify(String subscriptionSystemNotifyId) {
        SubscriptionSystemNotify subscriptionSystemNotify = subscriptionSystemNotifyMapper.selectOne(new LambdaQueryWrapper<SubscriptionSystemNotify>()
                .eq(SubscriptionSystemNotify::getId, subscriptionSystemNotifyId)
                .gt(SubscriptionSystemNotify::getStatus, 100));
        subscriptionSystemNotify.setStatus(subscriptionSystemNotify.getStatus() - 100);
        return subscriptionSystemNotifyMapper.updateById(subscriptionSystemNotify);
    }

    /**
     * 保存系统通知
     *
     * @param systemNotify
     */
    public void saveSystemNotify(SystemNotify systemNotify) {
        baseMapper.insert(systemNotify);
    }

    /**
     * 修改系统通知
     *
     * @param systemNotify
     * @return
     */
    public Integer updateSystemNotify(SystemNotify systemNotify) {
        return baseMapper.updateById(systemNotify);
    }


    /**
     * 删除系统通知
     *
     * @param systemNotifyId 系统通知Id
     */
    public Integer deleteSystemNotify(Long systemNotifyId) {
        int i = baseMapper.deleteById(systemNotifyId);
        if (i > 0) {
            //删除订阅系统通知
            this.deleteSubscriptionSystemNotify(systemNotifyId);
        }
        return i;
    }

    /**
     * /删除订阅系统通知
     *
     * @param systemNotifyId 系统通知Id
     * @return
     */
    private Integer deleteSubscriptionSystemNotify(Long systemNotifyId) {
        return subscriptionSystemNotifyMapper.delete(new LambdaUpdateWrapper<SubscriptionSystemNotify>().eq(SubscriptionSystemNotify::getSystemNotifyId, systemNotifyId));
    }
}
